﻿// Decompiled with JetBrains decompiler
// Type: DnProcessSimulateCommands.ExportToRTR.CUiExportToRTRWindowViewModel
// Assembly: DnProcessSimulateCommands, Version=2402.0.0.890, Culture=neutral, PublicKeyToken=null
// MVID: A885D881-AEDF-447E-852A-6F13102E089C
// Assembly location: C:\Program Files\Tecnomatix_2402\eMPower\DotNetCommands\DnProcessSimulateCommands.dll

using DnProcessSimulateCommands.ExportToRTR.Resources;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Windows;
using System.Windows.Forms;
using System.Windows.Threading;
using Tecnomatix.Engineering;
using Tecnomatix.Engineering.Ui.WPF;
using Tecnomatix.Engineering.Utilities;


namespace DnProcessSimulateCommands.ExportToRTR{

public class CUiExportToRTRWindowViewModel : CUiExportToRTRObservable
{
  private CApExportToRTRApp m_app;
  public CUiExportToRTRProgressHandler _progressHandler;
  private CUiExportToRTRContentDataHandler _contentDataHandeler = new CUiExportToRTRContentDataHandler();
  private CApExportToRTRStatusManager _statusManager = new CApExportToRTRStatusManager();
  private Visibility _errorMessageWindowCommandActive = Visibility.Hidden;
  private Visibility _errorMessageWindowCommandShaded;
  private bool _canOpenErrorMessageWindow = true;
  private Dispatcher _dispatcher;
  private string _currentStatusLable;
  private bool _inCreation = true;
  private Cursor _currentCursor;
  private CUiExportToRTRWindowViewModel.StatusType _currentStatus;
  private bool _outOfProgressScope;
  private Visibility _warningVisible = Visibility.Hidden;
  private Visibility _okVisible = Visibility.Hidden;
  private Visibility _errorVisible = Visibility.Hidden;
  private Visibility _exportingVisible = Visibility.Hidden;
  private Visibility _initializeVisible = Visibility.Hidden;
  private string _exportMessage;
  private string _progressLabel = "";
  private double _prohressValue;

  public static event RTRExportYamlEndEventHandler ExportEndEvent;

  public CUiExportToRTROutputViewModel OutputVm { get; set; }

  public CUiExportToRTRContentViewModel ContentVm { get; set; }

  public CUiExportToRTRWindowCommand ExportCommand { get; set; }

  public CUiExportToRTRWindowCommand OpenStatusInErrorViewer { get; set; }

  public CUiExportToRTRWindowGenericCommand<TxWindow> CloseCommand { get; set; }

  public Action CloseAction { get; set; }

  public Visibility ErrorMessageWindowCommandActive
  {
    get => this._errorMessageWindowCommandActive;
    set
    {
      this.Set<Visibility>(ref this._errorMessageWindowCommandActive, value, nameof (ErrorMessageWindowCommandActive));
    }
  }

  public Visibility ErrorMessageWindowCommandShaded
  {
    get => this._errorMessageWindowCommandShaded;
    set
    {
      this.Set<Visibility>(ref this._errorMessageWindowCommandShaded, value, nameof (ErrorMessageWindowCommandShaded));
    }
  }

  public bool CanOpenErrorMessageWindow
  {
    get => this._canOpenErrorMessageWindow;
    set
    {
      if (value == this._canOpenErrorMessageWindow)
        return;
      this.ErrorMessageWindowCommandActive = value ? Visibility.Visible : Visibility.Hidden;
      this.ErrorMessageWindowCommandShaded = value ? Visibility.Hidden : Visibility.Visible;
      this.Set<bool>(ref this._canOpenErrorMessageWindow, value, nameof (CanOpenErrorMessageWindow));
    }
  }

  internal Dispatcher CurrentDispatcher
  {
    get => this._dispatcher;
    set
    {
      this._dispatcher = value;
      this._contentDataHandeler.CurrentDispatcher = this._dispatcher;
      this.ContentVm.CurrentDispatcher = this._dispatcher;
    }
  }

  internal bool InCreation
  {
    get => this._inCreation;
    set
    {
      this._inCreation = value;
      this._contentDataHandeler.InCreation = value;
    }
  }

  public bool OutOfProgressScope
  {
    get => this._outOfProgressScope;
    set
    {
      this.Set<bool>(ref this._outOfProgressScope, value, nameof (OutOfProgressScope));
      this.ComputeCanOpenErrorMessage();
    }
  }

  public Visibility WarningVisible
  {
    get => this._warningVisible;
    set => this.Set<Visibility>(ref this._warningVisible, value, nameof (WarningVisible));
  }

  public Visibility OkVisible
  {
    get => this._okVisible;
    set => this.Set<Visibility>(ref this._okVisible, value, nameof (OkVisible));
  }

  public Visibility ErrorVisible
  {
    get => this._errorVisible;
    set => this.Set<Visibility>(ref this._errorVisible, value, nameof (ErrorVisible));
  }

  public Visibility ExportingVisible
  {
    get => this._exportingVisible;
    set => this.Set<Visibility>(ref this._exportingVisible, value, nameof (ExportingVisible));
  }

  public Visibility InitializeVisible
  {
    get => this._initializeVisible;
    set => this.Set<Visibility>(ref this._initializeVisible, value, nameof (InitializeVisible));
  }

  public CUiExportToRTRProgressHandler ProgressDataHandler
  {
    set
    {
      this._progressHandler = value;
      this._contentDataHandeler.ProgressHandler = this._progressHandler;
      this._currentStatusLable = ExportToRTRStringTable.STATUS_BAR_IDLE;
      this.StartProgress(20.0, 1.0, ExportToRTRStringTable.STATUS_BAR_WIN_OPEN);
      this.SetStatus(CUiExportToRTRWindowViewModel.StatusType.Initialize);
      this._progressHandler.Increment(10);
    }
  }

  public string ExportMessage
  {
    get => this._exportMessage;
    set
    {
      this.Set<string>(ref this._exportMessage, value, nameof (ExportMessage));
      this.ComputeCanOpenErrorMessage();
    }
  }

  public string ProgressLabel
  {
    get => this._progressLabel;
    set => this.Set<string>(ref this._progressLabel, value, nameof (ProgressLabel));
  }

  public double ProgressValue
  {
    get => this._prohressValue;
    set => this.Set<double>(ref this._prohressValue, value, nameof (ProgressValue));
  }

  public CUiExportToRTRWindowViewModel()
  {
    this.OutputVm = new CUiExportToRTROutputViewModel(this._statusManager, new Action(this.RefereshStatus));
    this.ContentVm = new CUiExportToRTRContentViewModel(this._statusManager, new Action(this.RefereshStatus), new Action(this.ResetProgress), new Action<double, double, string>(this.StartProgressPending), this._contentDataHandeler);
    this.m_app = new CApExportToRTRApp(this.OutputVm, this._contentDataHandeler);
    this.ExportCommand = new CUiExportToRTRWindowCommand(new Action(this.OnExport), new Func<bool>(this.CanExport));
    this.CloseCommand = new CUiExportToRTRWindowGenericCommand<TxWindow>(new Action<TxWindow>(this.CloseWindow));
    this.OpenStatusInErrorViewer = new CUiExportToRTRWindowCommand(new Action(this.OnOpenStatusInErrorViewer), new Func<bool>(this.CanOpenInErrorViewer));
    this.InCreation = true;
  }

  internal void Init() => this.Init(new List<ITxOperation>());

  internal void Init(List<ITxOperation> operationsToExport)
  {
    this.ContentVm.Init(operationsToExport);
  }

  internal bool CanExport()
  {
    return this._currentStatus != CUiExportToRTRWindowViewModel.StatusType.Error;
  }

  private void RefereshStatus()
  {
    if (!this._statusManager.IsModified)
      return;
    this.RefreshMessages();
  }

  private void RefreshMessages()
  {
    StringBuilder statusBuilder = new StringBuilder();
    this._statusManager.Publish((CApExportToRTRStatusIssueBuilder) new CApEportToRTRStatusIssueBuilderString(statusBuilder));
    this.ExportMessage = statusBuilder.Length > 0 ? statusBuilder.ToString() : (string) null;
    if (this.ExportMessage == null)
    {
      this._currentStatusLable = ExportToRTRStringTable.STATUS_BAR_IDLE;
      this._currentStatus = CUiExportToRTRWindowViewModel.StatusType.Ok;
    }
    else
    {
      this._currentStatusLable = ExportToRTRStringTable.STATUS_BAR_THERE_ARE_ISSUES;
      this._currentStatus = this._statusManager.CurrentSeverity != CApExportToRTRStatusManager.Severity.Error ? CUiExportToRTRWindowViewModel.StatusType.Warning : CUiExportToRTRWindowViewModel.StatusType.Error;
    }
    if (!this.InCreation)
      this.SetStatus(this._currentStatus);
    this.ProgressLabel = this._currentStatusLable;
  }

  private bool ListHasObjects(List<string> listToCheck)
  {
    return listToCheck != null && listToCheck.Count > 0;
  }

  private void SetStatus(
    CUiExportToRTRWindowViewModel.StatusType statusType)
  {
    switch (statusType)
    {
      case CUiExportToRTRWindowViewModel.StatusType.Ok:
        this.WarningVisible = Visibility.Hidden;
        this.OkVisible = Visibility.Visible;
        this.ErrorVisible = Visibility.Hidden;
        this.ExportingVisible = Visibility.Hidden;
        this.InitializeVisible = Visibility.Hidden;
        break;
      case CUiExportToRTRWindowViewModel.StatusType.Warning:
        this.WarningVisible = Visibility.Visible;
        this.OkVisible = Visibility.Hidden;
        this.ErrorVisible = Visibility.Hidden;
        this.ExportingVisible = Visibility.Hidden;
        this.InitializeVisible = Visibility.Hidden;
        break;
      case CUiExportToRTRWindowViewModel.StatusType.Error:
        this.WarningVisible = Visibility.Hidden;
        this.OkVisible = Visibility.Hidden;
        this.ErrorVisible = Visibility.Visible;
        this.ExportingVisible = Visibility.Hidden;
        this.InitializeVisible = Visibility.Hidden;
        break;
      case CUiExportToRTRWindowViewModel.StatusType.Export:
        this.WarningVisible = Visibility.Hidden;
        this.OkVisible = Visibility.Hidden;
        this.ErrorVisible = Visibility.Hidden;
        this.ExportingVisible = Visibility.Visible;
        this.InitializeVisible = Visibility.Hidden;
        break;
      case CUiExportToRTRWindowViewModel.StatusType.Initialize:
        this.WarningVisible = Visibility.Hidden;
        this.OkVisible = Visibility.Hidden;
        this.ErrorVisible = Visibility.Hidden;
        this.ExportingVisible = Visibility.Hidden;
        this.InitializeVisible = Visibility.Visible;
        break;
    }
  }

  private void AppendMessaggesToMessageBuilder(
    ref StringBuilder messageBuilder,
    List<string> messages,
    string prefix)
  {
    if (messages == null)
      return;
    int count = messages.Count;
    if (count <= 0)
      return;
    if (messageBuilder.Length > 0)
      messageBuilder.Append("\n");
    for (int index = 0; index < count; ++index)
    {
      messageBuilder.Append(prefix);
      messageBuilder.Append(messages[index]);
      if (index < count - 1)
        messageBuilder.Append("\n");
    }
  }

  /// <summary>
  /// 执行导出入口（带 UI 控制）。
  /// 逐行说明：
  /// - 检查导出目录是否已存在，若存在则提示是否覆盖/删除。
  /// - 删除旧目录失败且允许显示 UI 时，弹出错误对话框并中止。
  /// - 最终进入 Export 执行实际导出逻辑。
  /// </summary>
  internal void OnExport(bool showUi, ref string errorMessag)
  {
    // 判断目标导出目录是否已存在
    if (Directory.Exists(this.OutputVm.FullExportPath))
    {
      // 目录已存在时，拼接提示信息（是否覆盖）
      string str = string.Format(ExportToRTRStringTable.DIRECTORY_ALREADY_EXISTS_ERROR_MSG, (object) this.OutputVm.FullExportPath);
      // 如果需要展示 UI，则弹出 Yes/No 对话框；否则默认返回 Yes 的数值分支（6）以继续
      if ((showUi ? (int) TxMessageBox.Show(str, CCoExportToRTRCmd.CmdName, MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation) : 6) == 7)
        // 用户选择 No（7）则取消导出
        return;
      try
      {
        // 选择继续时，递归删除旧的导出目录
        Directory.Delete(this.OutputVm.FullExportPath, true);
      }
      catch (Exception ex)
      {
        // 删除失败：检查是否确实还有子目录或文件占用导致无法删除
        DirectoryInfo directoryInfo = new DirectoryInfo(this.OutputVm.FullExportPath);
        if (directoryInfo.GetDirectories().Length == 0)
        {
          if (directoryInfo.GetFiles().Length == 0)
            // 如果既没有子目录也没有文件（竞态下可能已经被清空），则继续后续导出
            goto label_9;
        }
        // 若不显示 UI，则静默退出（由调用方决定如何处理）
        if (!showUi)
          return;
        // 显示错误提示，通知用户目录无法删除
        int num = (int) TxMessageBox.Show(string.Format(ExportToRTRStringTable.UNABLE_TO_DELETE_DIRECTORY, (object) this.OutputVm.FullExportPath), CCoExportToRTRCmd.CmdName, MessageBoxButtons.OK, MessageBoxIcon.Hand);
        // 删除失败且用户可见时，中止导出
        return;
      }
    }
label_9:
    // 开始真正的导出流程
    this.Export(showUi, ref errorMessag);
  }

  /// <summary>
  /// 无参导出入口，默认显示 UI 并忽略错误字符串。
  /// </summary>
  private void OnExport()
  {
    // 用于接收错误信息的占位字符串（未使用）
    string empty = string.Empty;
    // 默认以显示 UI 的方式执行导出
    this.OnExport(true, ref empty);
  }

  /// <summary>
  /// 实际导出逻辑：设置状态与进度，调用应用层导出，触发事件，必要时安装到 RTR。
  /// </summary>
  private void Export(bool showUi, ref string errorMessag)
  {
    // 切换到“导出中”状态（用于状态图标/可视状态）
    this.SetStatus(CUiExportToRTRWindowViewModel.StatusType.Export);
    // 更新进度栏标签文本
    this.ProgressLabel = ExportToRTRStringTable.STATUS_BAR_EXPORT;
    // 处理消息循环，刷新 UI，避免长时间无响应
    System.Windows.Forms.Application.DoEvents();
    // 调用应用层导出（核心导出过程），返回导出输出目录
    string outputPath = this.m_app.Export();
    // 若已订阅导出完成事件，则触发事件（携带输出路径与成功标记）
    RTRExportYamlEndEventHandler exportEndEvent = CUiExportToRTRWindowViewModel.ExportEndEvent;
    if (exportEndEvent != null)
      exportEndEvent((object) this, new ExportYamlEndEventArgs(outputPath, outputPath != ""));
    // 如用户选择“导出后安装项目”，则调用 RTR 安装命令。命令参数以 "输出路径;机器名" 的格式传入
    if (this.OutputVm.InstallProject && !new TxCommandsManager().ExecuteCommand("RealtimeRobotics.CCoRTRInstallProjectCommand", (object) $"{outputPath};{this.OutputVm.MachineName}"))
    {
      // 安装失败：组织错误信息
      string str = string.Format(ExportToRTRStringTable.RTR_EXPORT_INSTALL_FAILURE_ERROR, (object) outputPath, (object) this.OutputVm.MachineName);
      if (showUi)
      {
        // 需要 UI 时弹窗提示安装失败
        int num = (int) TxMessageBox.Show(str, CCoExportToRTRCmd.CmdName, MessageBoxButtons.OK, MessageBoxIcon.Hand);
      }
      else
        // 静默模式下，将错误信息通过 ref 返回
        errorMessag = str;
    }
    // 恢复进度栏文本到当前状态对应的标签
    this.ProgressLabel = this._currentStatusLable;
    // 恢复状态图标为当前计算出的状态（OK/Warning/Error）
    this.SetStatus(this._currentStatus);
    // 关闭窗口（由外部注入的 CloseAction 执行）
    this.CloseAction();
  }

  private void CloseWindow(TxWindow window) => ((Window) window)?.Close();

  internal void Initialize()
  {
    this.ResotreValuesFromRegistry();
    this._dispatcher.BeginInvoke((Delegate) (() =>
    {
      this.ProgressLabel = ExportToRTRStringTable.STATUS_BAR_WIN_OUTPUT_INIT;
      this._progressHandler.Increment(5);
    }), DispatcherPriority.Background);
    this.OutputVm.Initialize();
    this._dispatcher.BeginInvoke((Delegate) (() =>
    {
      this._progressHandler.Increment(5);
      this.InCreation = false;
      this.ResetProgress();
    }), DispatcherPriority.Background);
  }

  internal void ResetProgress()
  {
    if (this.InCreation)
      return;
    this._progressHandler.Reset();
    this.ProgressLabel = this._currentStatusLable;
    if (this._currentCursor != (Cursor) null)
    {
      Cursor.Current = this._currentCursor;
      this._currentCursor = (Cursor) null;
      this.OutOfProgressScope = true;
    }
    this.SetStatus(this._currentStatus);
  }

  internal void StartProgressPending(double range, double stepSize, string label)
  {
    if (!this.InCreation)
    {
      this.StartProgress(range, stepSize, label);
    }
    else
    {
      this._progressHandler.AddToRange(range, stepSize);
      this.ProgressLabel = label;
    }
  }

  internal void StartProgress(double range, double stepSize, string label)
  {
    this.ProgressLabel = label;
    this._progressHandler.Start(range == 0.0 ? 10.0 : range, stepSize);
    this._currentCursor = Cursor.Current;
    Cursor.Current = Cursors.WaitCursor;
    this.OutOfProgressScope = false;
  }

  private void OnOpenStatusInErrorViewer()
  {
    TxErrorWindow.ShowDialog("RTR Status Window", "Some Upper Text", new Hashtable()
    {
      {
        (object) "One",
        (object) new List<string>()
        {
          "One.One",
          "One.Two",
          "One.Three"
        }
      },
      {
        (object) "Two",
        (object) new List<string>() { "Two.One", "Two.Two" }
      }
    }, new Hashtable()
    {
      {
        (object) "Three",
        (object) new List<string>()
        {
          "Three.One",
          "Three.Two",
          "Three.Three",
          "Three.Four"
        }
      },
      {
        (object) "Four",
        (object) new List<string>() { "Four.One" }
      }
    }, true);
  }

  private bool CanOpenInErrorViewer()
  {
    return !string.IsNullOrEmpty(this._exportMessage) && this._exportMessage.Length > 0;
  }

  private void ComputeCanOpenErrorMessage()
  {
    this.CanOpenErrorMessageWindow = this.OutOfProgressScope && this.CanOpenInErrorViewer();
  }

  private void ResotreValuesFromRegistry()
  {
    string str = CApExportToRTRUtils.ReadValueFromRegistry("UseWorkingFrame");
    if (!string.IsNullOrEmpty(str) && str == "False")
      CApExportToRTRExportManager.UseWorkingFrame = false;
    else
      CApExportToRTRExportManager.UseWorkingFrame = true;
  }

  private enum StatusType
  {
    Ok,
    Warning,
    Error,
    Export,
    Initialize,
  }
}
